Here’s another 5 minute job turning into a few hours of trial and error trying to get Internet Explorer and Mozilla to behave the same.
Help Builder generates plain HTML output in addition to CHM, Html Help 2.0 and Word output. The output it generates is a framed interface like this documentation for the West Wind Web Store:
http://www.west-wind.com/westwindwebstore/docs/
One of the things I do a lot of is point people at the documentation through our support Message Board, so if a question comes up in the docs I can point them straight at the topic in question. For example, if they have a question about the PayPal support in the store I can point them at our support class for PayPal:
http://www.west-wind.com/westwindwebstore/docs/_1BN0W66XZ.htm
I can also do this in more visually appealing way by displaying both the TOC and the selected topic:
http://www.west-wind.com/westwindwebstore/docs/index.htm?page=_1BN0W66XZ.htm
In the current version of Help Builder this works fine in displaying the TOC and the topic, but the tree unfortunately is not updated to match ( it does in the sample though since it's updated with the new code) . A lot of topics are not single view topics, but require that you actually look at the whole topic tree, so I sat out today to change the behavior so that the tree is in sync when you use the page directive to go directly to a topic.
In fact you should see this behavior now in the tree if you navigated to the last link above.
As usual implementing the functionality for plain IE took about half an hour, but then testing in Mozilla immediately yielded a number of problems that IE conveniently overlooked. A few syntactical issues (the frames collection must be references with window.frames[] instead of window.frames()) and some differences in how Mozilla and IE handle errors against nulled nodes.
One of the things that I ran up against was the need to walk the document element hierarchy backwards. I know which topic ID I’m on, so from there I need to walk backwards and expand each of the items. In IE you can use the parentElement property to get a reference to the next higher node. Piece of cake. A short recursive while loop and off you are. Except of course, that Mozilla doesn’t support parentElement.
It turns out that both IE and Mozilla DO support parentNode and it happens to have the same behavior! Since debugging in the browser is oh so much fun, it took me a good hour by trial and error to derive at this solution. I didn’t even think that parentNode would work in Mozilla, since parentNode is more of an XMLDOM method and I figured if anything that would not be supported by Mozilla.
Once the finding and opening of all the nodes was in place, the next issue is trying to get the tree to scroll the element into view. You can use the scrollIntoView() function to bring the control into the viewable area. Unfortunately this also scrolled the horizontal display to right so another call to window.sroll() is needed to keep the view adjusted properly.
loOriginal.scrollIntoView(true);
window.scroll(-200,0);
I was surprised to see that scrollIntoView() works because it’s not listed – or maybe it’s just skipping that line …
The final function ended up looking like this:
function ExpandParents(lcId)
{
var loNode = document.getElementById(lcId);
if (loNode == null)
return;
AlwaysExpand(lcId);
var loOriginal = loNode
while( loNode!=null)
{
loNode = loNode.parentNode;
if (loNode == null)
break;
lcId = loNode.id;
if (lcId == null || lcId == "")
break;
if ( lcId.substr(0,1) == "_")
ExpandParents(lcId);
}
loOriginal.scrollIntoView(true);
window.scroll(-200,0);
}
function AlwaysExpand(lcID) {
var loNode = document.getElementById(lcID);
if (loNode==null)
return;
loNode.style.display="";
loNode = document.getElementById("IMG" + lcID);
if (loNode != null)
loNode.src = "bmp/minus.gif";
}
It’s so sad how much time goes into building and debugging even these moderately complex HTML interfaces. Anyway I hope that there are a few useful tips in here. The help pages above show how you can implement a tree like interface, it’s basically all done via script code with hiding and enabling the child nodes as needed.
Now off to add some search functionality…
Other Posts you might also like